<?php
namespace zake\foundation\able\traits;

use zake\foundation\able\stream\RwBufferAble;
use zake\foundation\reactor\Reactor;

/**
 * Trait BeeTrait
 * @package zake\foundation\able\traits
 *
 * @author liu.bin 2020-05-15 15:06
 */
trait BeeTrait
{
    protected $sessionId;


    public function setSessionId($sessionId)
    {
        $this->sessionId = $sessionId;
    }



    public function getSessionId()
    {
        return $this->sessionId;
    }



    /**
     * 指定客户端发送消息
     * @param $toSessionId
     * @param $sendBuffer
     * @param null $callback
     * @param array $param
     * @return false|int
     *
     * @author liu.bin 2020-05-01 10:20
     */
    public function writeBufferTo($toSessionId,$sendBuffer,$callback=null,$param=[])
    {


        /**
         * @var RwBufferAble $channel
         * @var RwBufferAble $cluster
         */

        // 1: 是否处于同一集群
        // 2: 是否处于同一进程
        // 3: 从reactor返回接收stream

        // 同进程内(cluster id 和 process id相同)      ：通过reactor获取
        // 不同的进程（cluster id相同，process id不同）  ：发送给不同进程的reactor
        // 不同的主机（cluster id，process id都不同）    ：发送给父进程channel
        $fromSessionId = $this->getSessionId();


        // 主机通信
        $cluster = 0XFF000000;
        if(($fromSessionId & $cluster) !== ($toSessionId & $cluster)){
            // 链接集群，发送消息
            $cluster = $this->getCluster();
            $cluster->writeBuffer("");
            return 1;
        }


        // 进程通信
        $process = 0X00FF0000;
        if(($fromSessionId & $process) !== ($toSessionId & $process)){
            // 需要连接本机的其它进程，发送消息
            $channel = $this->getChannel();
            return $channel->writeBuffer("");
        }


        // 链接通信
        $toConnect = Reactor::getConnect($toSessionId & 0X0000FFFF);
        if(empty($toConnect)){
            return false;
        }
        return $toConnect->writeBuffer($sendBuffer,$callback,$param);
    }
}